﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

using Skyhook.Core.Xml;

namespace Skyhook.Core.Configuration
{
    public class DataStorage
    {
        Dictionary<Type, IDataCollection<Data>> Storage = new Dictionary<Type, IDataCollection<Data>>();
        XmlDocumentsCache XmlCache = new XmlDocumentsCache();

        Dictionary<Type, IDataLoader<Data>> Loaders = new Dictionary<Type, IDataLoader<Data>>();

        public DataStorage()
        {
        }

        public void RegisterDataType<T>() where T : Data, new()
        {
            DataCollection<T> collection = new DataCollection<T>();
            Storage[typeof(T)] = collection;

            DataLoader<T> loader = new DataLoader<T>(collection);
            Loaders[typeof(T)] = loader;
        }

        public void LoadFromPath(string path)
        {
            ClearStorage();

            LoadXmlCacheIfNesessary(path);

            PreloadFromCache();
            LoadFromCache();
        }

        public void LoadSingleDataTypeFromPath<T>(string path) where T : Data, new()
        {
            Storage[typeof(T)].Clear();

            LoadXmlCacheIfNesessary(path);

            DataLoader<T> loader = Loaders[typeof(T)] as DataLoader<T>;

            loader.PreloadFromCache(XmlCache);
            loader.LoadFromCache(XmlCache);
        }

        void LoadXmlCacheIfNesessary(string path)
        {
            if (XmlCache.Path != path || XmlCache.IsLoaded == false)
            {
                XmlCache.LoadFromPath(path);
            }
        }

        void PreloadFromCache()
        {
            foreach (IDataLoader<Data> loader in Loaders.Values)
            {
                loader.PreloadFromCache(XmlCache);
            }
        }

        void LoadFromCache()
        {
            foreach (IDataLoader<Data> loader in Loaders.Values)
            {
                loader.LoadFromCache(XmlCache);
            }
        }

        void ClearStorage()
        {
            foreach (IDataCollection<Data> collection in Storage.Values)
            {
                collection.Clear();
            }
        }

        public T GetData<T>(string type) where T : Data, new()
        {
            return ((DataCollection<T>)Storage[typeof(T)])[type];
        }
    }
}
